package com.xhwl.logistics.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xhwl.common.enums.vehicle.PayTypeEnum;
import com.xhwl.common.enums.vehicle.RechargeTypeEnum;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.vehicle.VehcPayConfig;
import com.xhwl.common.vo.cent.vehicle.CarPayVo;
import com.xhwl.logistics.dao.VehcPayConfigDao;
import com.xhwl.logistics.service.IVehcCarService;
import com.xhwl.logistics.util.DateFormatUtil;
import com.xhwl.logistics.util.WeChatPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @description: 微信支付
 * @author: lu.Aaron
 * @create: 2021-08-12 14:29
 **/
//@RestController
@Slf4j
public class WeChatPayController {
    @Autowired
    private VehcPayConfigDao vehcPayConfigDao;
    @Autowired
    private IVehcCarService vehcCarService;

    private final Lock lock = new ReentrantLock();
    /**
     * 微信支付回调
     * @param request
     * @return
     */
    @RequestMapping(value = "/we-chat-pay/notify", method = RequestMethod.POST)
    public String payResultNotify(HttpServletRequest request) {

        //1.读取支付回调数据
        InputStream is=null;
        lock.lock();
        try {
            is= request.getInputStream();
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len=0;
            while ((len=is.read(buffer))!=-1){
                os.write(buffer,0,len);
            }
            is.close();
            os.close();
            //2.将回调数据转成XML字符串
            byte[] bytes = os.toByteArray();

            String XMLResult = new String(bytes, "utf-8");
            //3.将XML字符串转成Map结构
            Map<String, String> resultMap = WeChatPayUtil.xmlToMap(XMLResult);

            //4.1获取自定义参数attach：
            String attach = resultMap.get("attach");
            String out_trade_no = resultMap.get("out_trade_no");
            String total_fee = resultMap.get("total_fee");
            String time_end = resultMap.get("time_end");
            //商家数据包解析(即统一下单携带的附加参数)
            JSONObject jsonObject = JSON.parseObject(attach);
            Integer rcType = (Integer) jsonObject.get("rct");
            Integer projectId =(Integer) jsonObject.get("pId");
            Short industryId =(Short) jsonObject.get("idId");
            String plateNumber =(String) jsonObject.get("pn");
            Integer payerAccountId =(Integer) jsonObject.get("paId");
            String payer =(String) jsonObject.get("pr");
            //查询对接微信支付需要的商户相关信息
            VehcPayConfig vehcPayConfig = vehcPayConfigDao.selectOne(new QueryWrapper<VehcPayConfig>().eq("project_id", projectId).eq("type", PayTypeEnum.WECHAT));
            if (WeChatPayUtil.isSignatureValid(XMLResult,vehcPayConfig.getPartnerKey())) {
                CarPayVo carPayVo = new CarPayVo();
                carPayVo.setPayType(PayTypeEnum.WECHAT);
                carPayVo.setAmount(Integer.valueOf(total_fee));
                carPayVo.setOutTradeNo(out_trade_no);
                carPayVo.setTimeEnd(time_end);
                if (RechargeTypeEnum.MONTH_CARD_RECHARGE.getKey().equals(rcType)) {
                    carPayVo.setRechargeType(RechargeTypeEnum.MONTH_CARD_RECHARGE);
                }else if(RechargeTypeEnum.STORE_CARD_RECHARGE.getKey().equals(rcType)){
                    carPayVo.setRechargeType(RechargeTypeEnum.STORE_CARD_RECHARGE);
                }if(RechargeTypeEnum.TEMP_PARK_RECHARGE.getKey().equals(rcType)){
                    carPayVo.setRechargeType(RechargeTypeEnum.TEMP_PARK_RECHARGE);
                }
                carPayVo.setProjectId(projectId);
                carPayVo.setPlateNumber(plateNumber);
                carPayVo.setPayerAccountId(payerAccountId);
                carPayVo.setPayer(payer);
                String message =null;
                ResultJson resultJson =null;
                //验证签名通过
                if (RechargeTypeEnum.TEMP_PARK_RECHARGE.getKey().equals(rcType)) {
                    //异步处理临停缴费回调业务处理
                    resultJson = vehcCarService.tempParkFeeRecharge(carPayVo, industryId);

                }else if(RechargeTypeEnum.STORE_CARD_RECHARGE.getKey().equals(rcType)){
                    //异步处理储值卡充值回调业务处理
                    Integer carId = (Integer) jsonObject.get("cid");
                    carPayVo.setCarId(carId);
                    resultJson = vehcCarService.storeCarRecharge(carPayVo, industryId);

                }else if(RechargeTypeEnum.MONTH_CARD_RECHARGE.getKey().equals(rcType)){
                    //异步处理月卡业务处理
                    Integer monthNum = (Integer) jsonObject.get("mn");
                    //String validBeginTime = (String) jsonObject.get("vbt");
                    String validEndTime = (String) jsonObject.get("vet");
                    Integer carId = (Integer) jsonObject.get("cid");
                    carPayVo.setCarId(carId);
                    carPayVo.setMonthNum(monthNum);
                    //carPayVo.setValidBeginTime(DateFormatUtil.stringDate2Date(validBeginTime));
                    carPayVo.setValidBeginTime(DateFormatUtil.stringDate2Date(validEndTime));
                    resultJson = vehcCarService.monthCarRecharge(carPayVo, industryId);

                }
                if (null!=resultJson&&resultJson.getState()) {
                    log.info("支付回调成功，业务执行完毕"+resultJson.getMessage()+"微信订单号:"+out_trade_no);
                    Map<String,String> respMap=new HashMap<>();
                    respMap.put("return_code","SUCCESS");
                    respMap.put("return_msg","OK");
                    return WeChatPayUtil.mapToXml(respMap);
                }
            }else {
                //验签失败
                Map<String,String> respMap=new HashMap<>();
                respMap.put("return_code","FAIL");
                respMap.put("return_msg","签名失败");
                log.info("支付回调,验签失败");
                return WeChatPayUtil.mapToXml(respMap);
            }

        } catch (Exception e) {
        }finally {
            lock.unlock();
        }
        return null;
    }
}

